﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KataBankOCR
{
    /// <summary>
    /// Class to contain all of the digit decoding details
    /// 
    /// Each digit is stores as a numLines X numChars representation
    /// </summary>
    class Digit
    {
        /// <summary>
        /// This is the number of lines a digit is stored in
        /// </summary>
        public const int numLines = 3;

        /// <summary>
        /// This is the number of characters wide each digit is stored as
        /// </summary>
        public const int numChars = 3;
        
        /// <summary>
        /// numberPatterns contains all numbers that can be read, assuming no errors
        /// </summary>
        private static Dictionary<string,char> numberPatterns = new Dictionary<string,char> {
                               { " _ " + 
                                 "| |" +
                                 "|_|", '0'},

                               { "   " + 
                                 "  |" +
                                 "  |", '1'},

                               { " _ " +
                                 " _|" +
                                 "|_ ", '2'},

                               { " _ " +
                                 " _|" +
                                 " _|", '3'},

                               { "   " +
                                 "|_|" +
                                 "  |", '4'},

                               { " _ " +
                                 "|_ " +
                                 " _|", '5'},

                               { " _ " +
                                 "|_ " +
                                 "|_|", '6'},

                               { " _ " +
                                 "  |" +
                                 "  |", '7'},

                               { " _ " +
                                 "|_|" +
                                 "|_|", '8'},

                               { " _ " +
                                 "|_|" +
                                 " _|", '9'} };
        /// <summary>
        /// oneBarChangeNumberPatterns contains all number patterns if one bar is missing 
        /// </summary>
        private static Dictionary<string, string> oneBarChangeNumberPatterns = new Dictionary<string, string> {
                               { " _ " + 
                                 "| |" +
                                 "|_|", "08"},

                               { "   " + 
                                 "| |" +
                                 "|_|", "0"},

                               { " _ " + 
                                 "|  " +
                                 "|_|", "06"},

                               { " _ " + 
                                 "| |" +
                                 "|_ ", "0"},

                               { " _ " + 
                                 "| |" +
                                 "| |", "0"},

                               { " _ " + 
                                 "| |" +
                                 " _|", "09"},

                               { " _ " + 
                                 "  |" +
                                 "|_|", "0"},

                               { "   " + 
                                 "  |" +
                                 "  |", "17"},

                               { "   " +
                                 "   " +
                                 "  |", "1"},

                               { "   " + 
                                 "  |" +
                                 "   ", "1"},

                               { "   " + 
                                 "| |" +
                                 "  |", "14"},

                               { "   " + 
                                 " _|" +
                                 "  |", "14"},

                               { "   " + 
                                 "  |" +
                                 "| |", "1"},

                               { "   " + 
                                 "  |" +
                                 " _|", "1"},

                               { " _ " +
                                 " _|" +
                                 "|_ ", "2"},

                               { "   " +
                                 " _|" +
                                 "|_ ", "2"},

                               { " _ " +
                                 " _ " +
                                 "|_ ", "2"},

                               { " _ " +
                                 "  |" +
                                 "|_ ", "2"},

                               { " _ " +
                                 " _|" +
                                 " _ ", "23"},

                               { " _ " +
                                 " _|" +
                                 "|  ", "2"},

                               { " _ " +
                                 "|_|" +
                                 "|_ ", "238"},

                               { " _ " +
                                 " _|" +
                                 "|_|", "28"},

                               { " _ " +
                                 " _|" +
                                 " _|", "39"},

                               { "   " +
                                 " _|" +
                                 " _|", "3"},

                               { " _ " +
                                 " _ " +
                                 " _|", "35"},

                               { " _ " +
                                 "  |" +
                                 " _|", "37"},

                               { " _ " +
                                 " _|" +
                                 "  |", "37"},

                               { "   " +
                                 "|_|" +
                                 "  |", "49"},

                               { "   " +
                                 "|_ " +
                                 "  |", "4"},

                               { "   " +
                                 "|_|" +
                                 "   ", "4"},

                               { "   " +
                                 "|_|" +
                                 "| |", "4"},

                               { "   " +
                                 "|_|" +
                                 " _|", "49"},

                               { " _ " +
                                 "|_|" +
                                 "  |", "49"},

                               { " _ " +
                                 "|_ " +
                                 " _|", "569"},

                               { "   " +
                                 "|_ " +
                                 " _|", "5"},


                               { " _ " +
                                 "|  " +
                                 " _|", "5"},

                               { " _ " +
                                 "|_ " +
                                 " _ ", "5"},

                               { " _ " +
                                 "|_ " +
                                 "  |", "5"},

                               { " _ " +
                                 "|_ " +
                                 "|_|", "568"},

                               { "   " +
                                 "|_ " +
                                 "|_|", "6"},

                               { " _ " +
                                 " _ " +
                                 "|_|", "6"},

                               { " _ " +
                                 "|_ " +
                                 "|_ ", "6"},

                               { " _ " +
                                 "|_ " +
                                 "| |", "6"},

                               { " _ " +
                                 "  |" +
                                 "  |", "17"},

                               { " _ " +
                                 "   " +
                                 "  |", "7"},

                               { " _ " +
                                 "  |" +
                                 "   ", "7"},

                               { " _ " +
                                 "| |" +
                                 "  |", "7"},

                               { " _ " +
                                 "  |" +
                                 "| |", "7"},

                               { " _ " + 
                                 "|_|" +
                                 "|_|", "0689"},

                               { "   " +
                                 "|_|" +
                                 "|_|", "8"},
 
                               { " _ " +
                                 "|_|" +
                                 "| |", "8"},

                               { " _ " +
                                 "|_|" +
                                 " _|", "3589"},
                                 
                               { " _ " +
                                 "|_|" +
                                 " _ ", "9"}};


        /// <summary>
        /// Static method to read string array items and return a character it represents
        /// </summary>
        /// <param name="strings">Array of strings containing number digit patterns from OCR scanner. This string set can contain 
        /// multiple number digits.  They must be in one after the other, no spaces between them.</param>
        /// <param name="startIndex">Index to read character from, so 0 for first digit, Digits.numChars for the
        /// second digit etc.</param>
        /// <returns>Returns a character representing the digit number read or a '?' if a number cannot be decoded from 
        /// the strings</returns>
        public static char decodeDigit(string[] strings, int startIndex)
        {
            StringBuilder encodedString = new StringBuilder();

            for (int strIndex = 0; strIndex < numLines; strIndex++)
            {
                encodedString.Append(strings[strIndex].Substring(startIndex,numChars));
            }
            return toChar(encodedString.ToString());
        }

        /// <summary>
        /// Method to turn an encodeed string into a character.
        /// </summary>
        /// <param name="encodedString">Encoded character where line1 appended to line2 appended to line3 to create
        /// a single string representing the digit</param>
        /// <returns>Returns a character representing the digit number read or a '?' if a number cannot be decoded from 
        /// the strings</returns>
        private static char toChar(string encodedString)
        {
            if (numberPatterns.ContainsKey(encodedString))
            {
                return numberPatterns[encodedString];
            } 
            else 
            {
                return'?';
            }
        }

        public static string oneBarAdjustDecode(string[] strings, int startIndex)
        {
            StringBuilder encodedString = new StringBuilder();

            for (int strIndex = 0; strIndex < numLines; strIndex++)
            {
                encodedString.Append(strings[strIndex].Substring(startIndex,numChars));
            }

            if (oneBarChangeNumberPatterns.ContainsKey(encodedString.ToString()))
            {
                return oneBarChangeNumberPatterns[encodedString.ToString()];
            } 
            else 
            {
                return"?";
            }
        }
    }
}
